""" FuzzyRuleExpression
    
    
    
    2006 (C) Pollini Andrea

    this file si released under LGPL license 2.0  or above.
"""

__author__ = "Pollini Andrea  nelson1977@gmail.com"

from FuzzyOperators import op_and,op_or,IS,ISNOT
import FuzzyVariable
import MembershipFunctions
import math

class FuzzyRuleExpression(object):
    """
    test
    
    test
    """
    def __init__(self, **kwargs):
        """
            @param term1: test
        """
        self.l_term = kwargs.get('term1',None)
        self.r_term = kwargs.get('term2',None)
        self.connection_op = kwargs.get('op',op_and)
     
    def setConnectionOp(self,anOp):
        self.connection_op = anOp
     
    def addTerm(self, aFuzzyStatement):
        if self.l_term is None:
            self.l_term = aFuzzyStatement
        elif self.r_term is None:
            self.r_term = aFuzzyStatement
        elif self.isFuzzyRule(self.l_term):
            self.l_term.addTerm(aFuzzyStatement)  
        elif self.isFuzzyRule(self.r_term):
            self.r_term.addTerm(aFuzzyStatement)
        else:
            raise "Impossible to add the rule!"
    
    
    def __call__(self, values):
        term1_v = 0.0
        term2_v = 0.0
        
        if self.isFuzzyRule(self.l_term):
            self.l_term(values)
        elif self.l_term is not None:
            term1_v = self.l_term(values[ self.l_term.var.name ])
        elif self.l_term is None:
            term1_v = -1
        else:
            raise "Error evaluating term1"
 
        if self.isFuzzyRule(self.r_term):
            self.r_term(values)
        elif self.r_term is not None:
            term2_v = self.r_term(values[ self.r_term.var.name ])
        elif self.r_term is None:
             term2_v = -1
        else:
            raise "Error evaluating term1"
       
        result = 0.0
        
        if self.l_term is None and self.r_term is None:
            return -1
        elif self.l_term is None: result = term2_v
        elif self.r_term is None: result = term1_v
        else: result = term1_v |self.connection_op| term2_v
        
        return result   
        
        
    def isFuzzyRule(self,aTerm):
        return isinstance(aTerm,FuzzyRuleExpression)
    
    
    def __str__(self):
        #string_rep = ""
        
        #if self.r_term is None:
        #    string_rep = " %s " % ( self.l_term)
        #else:
        string_rep = "(%s %s %s)" % ( self.l_term,self.connection_op,self.r_term)
        
        return string_rep
        
if __name__ == '__main__':
    frule = FuzzyRuleExpression()
    
    
    fv  = FuzzyVariable.FuzzyVariable("prova")
    fv.add(MembershipFunctions.make_membership_function("TRIANGULAR","basso",values=[0,1.2,2.5]))
    fv.add(MembershipFunctions.make_membership_function("TRIANGULAR","medio",values=[1,2.2,4.5]))
    fv.add(MembershipFunctions.make_membership_function("TRIANGULAR","alto",values=[2,4.2,5]))

    fv1  = FuzzyVariable.FuzzyVariable("prova1")
    fv1.add(MembershipFunctions.make_membership_function("TRIANGULAR","basso",values=[0,1.2,2.5]))
    fv1.add(MembershipFunctions.make_membership_function("TRIANGULAR","medio",values=[1,2.2,4.5]))
    fv1.add(MembershipFunctions.make_membership_function("TRIANGULAR","alto",values=[2,4.2,5]))
       
    fterm1 =  IS(fv,"basso")
    fterm2 =  ISNOT(fv1,"medio")
    fterm3 =  IS(fv1,"alto")
    frule.addTerm(fterm1)
    
    frule1 = FuzzyRuleExpression()    
    frule1.addTerm(fterm2)
    frule1.addTerm(fterm3)
    frule1.setConnectionOp(op_or)
    
    frule.addTerm(frule1)
    print frule({'prova':1.2,'prova1':1.2})
    print frule